/**
 *  Java Api For Ecco Generated Applications 
 *  
 *  Copyright (C) 2000  by PDTec GmbH 
 *
 * @author  Michael Weirich
 */

package pdtec.ecco.inst;

import pdtec.ecco.meta.Type;
import pdtec.ecco.meta.EccoException;

/**
 * Objects of class Value are proxies for instances in the underlying 
 * ecco application.
 *
 * @see  pdtec.ecco.inst.Instance
 * @see  pdtec.ecco.inst.AggregateValue
 */
public class Value {
    
    /** Internal object id. This field value is set automatically. 
    * @see pdtec.ecco.inst.Value#createByType(Type)
    * @see pdtec.ecco.inst.Value#get(int,long)
    */
    protected long id;
    
    /** Associated Application id. This field value is set automatically.
     *
     * @see pdtec.ecco.inst.Value#createByType(Type)
     * @see pdtec.ecco.inst.Value#get(int,long)
     */
    protected int appId;

    /** Logical constant FALSE. */
    public static int ECCO_FALSE = 0;

    /** Logical constant UNKNOWN. */
    public static int ECCO_UNKNOWN = 1;

    /** Logical constant TRUE. */
    public static int ECCO_TRUE = 2;

    /** Constructor enables instance creation by type. */
    public Value(Type type) {
	try {
	    createByType(type);
	} catch (Exception e) {
	    System.out.println(e.toString());
	} // catch
    } // constructor
    
    /** Constructor for string. */
    public Value(String val, Type type) {
	try {
	    createByType(type);
	    assignString(val);
	} catch(Exception e) {
	    System.out.println(e.toString());
	} // catch
    } // string constructor
    
    /** Constructor for integer. */
    public Value(int val, Type type) {
	try {
	    createByType(type);
	    assignInt(val);
	} catch(Exception e) {
	    System.out.println(e.toString());
	} // catch
    } // int constructor
    
    /** Constructor for long integer. */
    public Value(long val, Type type) {
	try {
	    createByType(type);
	    assignLong(val);
	} catch(Exception e) {
	    System.out.println(e.toString());
	} // catch
    } // long constructor
    
    /** Constructor for double. */
    public Value(double val, Type type) {
	try {
	    createByType(type);
	    assignDouble(val);
	} catch(Exception e) {
	    System.out.println(e.toString());
	} // catch
    } // double constructor

    /** Constructor for boolean. */
    public Value(boolean val, Type type) {
	try {
	    createByType(type);
	    assignBoolean(val);
	} catch(Exception e) {
	    System.out.println(e.toString());
	} // catch
    } // boolean constructor

    /** This constructor is protected since instance creation is delegated to the static
     * {@link #get(int,long) get(..) } method.
     * @see #get(int,long)
     */
    protected Value(int appId, long id) {
	this.id = id;
	this.appId = appId;
    } // constructor
    
    /** Creates an ecco application instance by type and sets the fields
     * id and appId of this object.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    protected native synchronized void createByType(Type type) throws EccoException;

    /** Returns true if value exists otherwise false.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs */
    public native synchronized boolean exists() throws EccoException;
    
    /** Returns the id.
     */
    public long getId() {
	return(id);
    } // getId

    /** Returns the application id.
     */
    public long getAppId() {
	return(appId);
    } // getId
    
    /** This Method creates objects of class Value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    static public native synchronized Value get(int appId, long id) throws EccoException;
    
    /** Converts Values to string.
     */
    public native synchronized String toString();
    
    // later..
    //public native synchronized Object toObject() throws EccoException;
    
    /** Returns the type of the value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized Type getType() throws EccoException;
    
    /** Assigns value object.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized void assign(Value obj) throws EccoException;
    
    /** Assigns string value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized void assignString(String value) throws EccoException;
    
    /** Assigns int value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public synchronized void assignInt(int value) throws EccoException {
	assignLong((long) value);
    } // assign
    
    /** Assigns long value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized void assignLong(long value) throws EccoException;
    
    /** Assigns double value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized void assignDouble(double value) throws EccoException;

    /** Assigns boolean value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public synchronized void assignBoolean(boolean value) throws EccoException { 
	if( value == true) 
	    assignInt(ECCO_TRUE);
	else
	    assignInt(ECCO_FALSE);
    } // assignBoolean

    /** Returns string value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized String getString() throws EccoException;
    
    /** Returns int value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public  synchronized int getInt() throws EccoException {
	return((int) getLong());
    } // getInt
    
    /** Returns long value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized long getLong() throws EccoException;
    
    /** Returns double value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized double getDouble() throws EccoException;

    /** Returns boolean value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public boolean getBoolean() throws EccoException {
	int result;
	result = getInt();
	
	// interpret integer result
	if( result == ECCO_TRUE)
	    return(true);
	else 
	    return(false);	
    } // getBoolean

    /** Returns type list of class Value.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized String[] typeOf() throws EccoException;

    /** Evaluates expression and applies it to "this".
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized Value evalExpr(String expression) throws EccoException;

    /** Check for identity.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized boolean isIdentical(Value cmp) throws EccoException;

    /** Check for equality.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized boolean isEqual(Value cmp) throws EccoException;

    /** Check for value order.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized boolean valOrder(Value cmp) throws EccoException;

    /** Check for reference order.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    public native synchronized boolean refOrder(Value cmp) throws EccoException;

    /** This method is called when object is finalized.
     * @exception pdtec.ecco.meta.EccoException in case an error occurs
     */
    protected native synchronized void delete() throws EccoException;

    /** Finalizes objects of class Value. */
    protected void finalize() {
	try{
	    if(appId != -1)
		delete();
	} catch(Exception e) {
	    System.out.println(e.toString());
	} // catch 
    } // finalize

} // class Value









